"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
exports.__esModule = true;
exports.PushUtil = void 0;
/**
 * 阿里云ddns，使用方法参考README
 * @author kangkang
 * @date 2021-12-26
 * @gitee https://gitee.com/god007/z4-ddns
 *
 *
============Quantumultx===============
[task_local]
0 *\/3 * * * ? aliyun-ddns.js, tag=阿里云ddns, img-url=, enabled=true

================Loon==============
[Script]
cron "0 *\/3 * * * ?" script-path=aliyun-ddns.js, tag=阿里云ddns

===============Surge=================
阿里云ddns = type=cron,cronexp="0 *\/3 * * * ?",wake-system=1,timeout=3600,script-path=aliyun-ddns.js

============小火箭=========
阿里云ddns = type=cron,script-path=aliyun-ddns.js, cronexpr="0 *\/3 * * * ?", timeout=3600, enable=true

 */
var alidns20150109_1 = require("@alicloud/alidns20150109"), $Alidns20150109 = alidns20150109_1;
// 依赖的模块可通过下载工程中的模块依赖文件或右上角的获取 SDK 依赖信息查看
var $OpenApi = require("@alicloud/openapi-client");
var $tea = require("@alicloud/tea-typescript");
var tea_util_1 = require("@alicloud/tea-util");
var https = require("https");
var http = require("http");
var PushUtil = /** @class */ (function () {
    function PushUtil() {
    }
    PushUtil.urlencode = function (str) {
        str = (str + '').toString();
        return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
            replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
    };
    PushUtil.httpGet = function (url) {
        console.log("处理推送通知----开始:" + url);
        var data = "";
        var req = null;
        if (url.startsWith("https")) {
            req = https.get(url, function (res) {
                res.on('data', function (chunk) {
                    data += chunk;
                });
                res.on('end', function () {
                    console.log("处理推送通知----结果:" + data);
                });
            });
        }
        else {
            req = http.get(url, function (res) {
                res.on('data', function (chunk) {
                    data += chunk;
                });
                res.on('end', function () {
                    console.log("处理推送通知----结果:" + data);
                });
            });
        }
        req.on('error', function (e) {
            console.log("处理推送通知----异常:" + e);
        });
        req.end();
    };
    PushUtil.html_template = "<td width=\"720\" height=\"32\" colspan=\"2\"><table width=\"95%\" cellspacing=\"0\" cellpadding=\"0\" bordercolor=\"#666666\" border=\"0\" bgcolor=\"#FFFFFF\" style=\"font-size:12px;font-weight:normal;border-collapse:collapse;\"><tbody><tr style=\"background-color:#e4e4e4;\"><th width=\"12%\" style=\"border:1px solid #ccc; height:32px;\">类型</th><th width=\"20%\" style=\"border:1px solid #ccc; height:32px;\">记录值</th><th width=\"\" style=\"border:1px solid #ccc; height:32px;\">ip地址</th></tr>IP4_LINE IP6_LINE</tbody></table></td><p style=\"font-size:12px;font-weight:normal;\"> 本推送来源: <a href='https://gitee.com/god007/z4-ddns.git'>z4-ddns</a> by <a href=\"https://www.chenweikang.top/\">左手代码右手诗</a></p>";
    PushUtil.ip4_template = "<tr><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\">IPV4</td><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\">IP4_KEY</td><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\">修改前: IP4_CHANGE_BEFORE<br>修改后: IP4_CHANGE_AFTER</td></tr>";
    PushUtil.ip6_template = "<tr><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\">IPV6</td><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\">IP6_KEY</td><td style=\"border:1px solid #ccc;word-break:break-all;padding:4px\"> 修改前: IP6_CHANGE_BEFORE<br>修改后: IP6_CHANGE_AFTER</td></tr>";
    PushUtil.pushplus_api = "http://www.pushplus.plus/send";
    PushUtil.ftqq_api = "https://sctapi.ftqq.com";
    PushUtil.pushConfigs = [
        {
            type: function () {
                return "pushplus";
            },
            getApi: function () {
                return PushUtil.pushplus_api;
            },
            push: function (title, content) {
                /**
                 * # PUSH_PLUS_TOKEN = "" # pushplud 的token
                 * # PUSH_KEY="" # 方糖的key
                 */
                var token = process.env.PUSH_PLUS_TOKEN ? process.env.PUSH_PLUS_TOKEN : "";
                if (token == "") {
                    console.log("处理推送通知---请在环境变量填写参数:PUSH_PLUS_TOKEN");
                    return;
                }
                //http://www.pushplus.plus/send?token=xx&title=XXX&content=XXX&template=html
                var api = PushUtil.pushplus_api + "?token=" + token + "&title=" + PushUtil.urlencode(title) + "&content=" + PushUtil.urlencode(content) + "&template=html";
                PushUtil.httpGet(api);
            }
        },
        {
            type: function () {
                return "ftqq";
            },
            getApi: function () {
                return PushUtil.ftqq_api;
            },
            push: function (title, content) {
                var token = process.env.PUSH_KEY ? process.env.PUSH_KEY : "";
                if (token == "") {
                    console.log("处理推送通知---请在环境变量填写参数:PUSH_KEY");
                    return;
                }
                var api = PushUtil.ftqq_api + "/" + token + ".send?title=" + PushUtil.urlencode(title) + "&desp=" + PushUtil.urlencode(content);
                PushUtil.httpGet(api);
            }
        },
    ];
    return PushUtil;
}());
exports.PushUtil = PushUtil;
var Client = /** @class */ (function () {
    function Client() {
    }
    Client.matchIp4 = function (input) {
        var reg = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g;
        var math = input.match(reg);
        return math ? math[0] : "";
    };
    Client.matchIp6 = function (input) {
        var reg = /([0-9a-z]*:{1,4}){1,7}[0-9a-z]{1,4}/g;
        var math = input.match(reg);
        return math ? math[0] : "";
    };
    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    Client.createClient = function (accessKeyId, accessKeySecret) {
        var config = new $OpenApi.Config({
            // 您的AccessKey ID
            accessKeyId: accessKeyId,
            // 您的AccessKey Secret
            accessKeySecret: accessKeySecret
        });
        // 访问的域名
        config.endpoint = "alidns.cn-hangzhou.aliyuncs.com";
        return new alidns20150109_1["default"](config);
    };
    /**
     * 获取ipv4
     * @returns Promise Object
     */
    Client.getIpv4 = function () {
        var DDNS_IP4_API = "https://myip.ipip.net";
        if (process.env.DDNS_IP4_API) {
            DDNS_IP4_API = process.env.DDNS_IP4_API;
        }
        console.log("处理ipv4----获取公网ipv4-开始:" + DDNS_IP4_API);
        var data = '';
        return new Promise(function (resolve, reject) {
            var req = https.get(DDNS_IP4_API, function (res) {
                res.on('data', function (chunk) {
                    data += chunk;
                });
                res.on('end', function () {
                    var ip4 = Client.matchIp4(data);
                    console.log("处理ipv4----获取公网ipv4-结果:" + ip4);
                    resolve({
                        result: ip4 != "" ? true : false,
                        data: ip4
                    });
                });
            });
            req.on('error', function (e) {
                resolve({
                    result: false,
                    data: ""
                });
            });
            req.end();
        });
    };
    /**
     * 获取ipv6
     * @returns Promise Object
     */
    Client.getIpv6 = function () {
        var DDNS_IP6_API = "https://api-ipv6.ip.sb/ip";
        if (process.env.DDNS_IP6_API) {
            DDNS_IP6_API = process.env.DDNS_IP6_API;
        }
        console.log("处理ipv6----获取公网ipv6-开始:" + DDNS_IP6_API);
        var data = '';
        return new Promise(function (resolve, reject) {
            var req = https.get(DDNS_IP6_API, function (res) {
                res.on('data', function (chunk) {
                    data += chunk;
                });
                res.on('end', function () {
                    var ip6 = Client.matchIp6(data);
                    console.log("处理ipv6----获取公网ipv6-结果:" + ip6);
                    resolve({
                        result: ip6 != "" ? true : false,
                        data: ip6
                    });
                });
            });
            req.on('error', function (e) {
                resolve({
                    result: true,
                    data: ""
                });
            });
            req.end();
        });
    };
    /**
     *
     * @param client sdk客户端
     * @param ipv4Domain ipv4解析域名
     */
    Client.handleIpv4 = function (client, ipv4Domain) {
        var key = ipv4Domain.substring(0, ipv4Domain.indexOf("."));
        var domain = ipv4Domain.substring(ipv4Domain.indexOf(".") + 1);
        //获取ipv4
        var changeResult = { domain: "", change: false, before: "", after: "", rr: "" };
        this.getIpv4().then(function (res) {
            return __awaiter(this, void 0, void 0, function () {
                var ip, describeDomainRecordsRequest, resp, queryResult, resultObj, domanResult, updateDomainRecordRequest, updateResp, error_1, addDomainRecordRequest, addResp;
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0:
                            ip = res.data;
                            if (!res.result) return [3 /*break*/, 9];
                            describeDomainRecordsRequest = new $Alidns20150109.DescribeDomainRecordsRequest({
                                domainName: domain,
                                typeKeyWord: "A",
                                RRKeyWord: key
                            });
                            console.log("处理ipv4----查询域名解析记录-开始:" + tea_util_1["default"].toJSONString($tea.toMap(describeDomainRecordsRequest)));
                            return [4 /*yield*/, client.describeDomainRecords(describeDomainRecordsRequest)];
                        case 1:
                            resp = _a.sent();
                            queryResult = tea_util_1["default"].toJSONString(resp.body.domainRecords);
                            resultObj = JSON.parse(queryResult);
                            domanResult = resultObj.record[0];
                            console.log("处理ipv4----查询域名解析记录-结果:" + queryResult);
                            changeResult.domain = domain;
                            changeResult.rr = key;
                            if (!domanResult) return [3 /*break*/, 6];
                            //更新域名记录
                            changeResult.before = domanResult.value;
                            changeResult.after = ip;
                            updateDomainRecordRequest = new $Alidns20150109.UpdateDomainRecordRequest({
                                TTL: 600,
                                priority: 1,
                                value: ip,
                                type: "A",
                                RR: key,
                                recordId: domanResult.recordId
                            });
                            console.log("处理ipv4----更新域名解析记录-开始:" + tea_util_1["default"].toJSONString($tea.toMap(updateDomainRecordRequest)));
                            _a.label = 2;
                        case 2:
                            _a.trys.push([2, 4, , 5]);
                            return [4 /*yield*/, client.updateDomainRecord(updateDomainRecordRequest)];
                        case 3:
                            updateResp = _a.sent();
                            changeResult.change = true;
                            console.log("处理ipv4----更新域名解析记录-完成:" + tea_util_1["default"].toJSONString($tea.toMap(updateResp)));
                            return [3 /*break*/, 5];
                        case 4:
                            error_1 = _a.sent();
                            console.log("处理ipv4----更新域名解析记录-完成:本次ip没有改变:" + error_1);
                            return [3 /*break*/, 5];
                        case 5: return [3 /*break*/, 8];
                        case 6:
                            addDomainRecordRequest = new $Alidns20150109.AddDomainRecordRequest({
                                TTL: 600,
                                priority: 1,
                                value: ip,
                                type: "A",
                                domainName: domain,
                                RR: key
                            });
                            return [4 /*yield*/, client.addDomainRecord(addDomainRecordRequest)];
                        case 7:
                            addResp = _a.sent();
                            changeResult.before = "无";
                            changeResult.after = ip;
                            changeResult.change = true;
                            console.log("处理ipv4----新增域名解析记录-完成:" + tea_util_1["default"].toJSONString($tea.toMap(addResp)));
                            _a.label = 8;
                        case 8:
                            //console.log("处理ipv4--变更结果:"+Util.toJSONString(changeResult))
                            Client.pushNotice(changeResult, null);
                            return [3 /*break*/, 10];
                        case 9:
                            console.error("处理ipv4----ipv4获取异常,跳过处理ipv4!");
                            _a.label = 10;
                        case 10: return [2 /*return*/];
                    }
                });
            });
        });
    };
    /**
     * 处理ipv6
     * @param client sdk客户端
     * @param ipv6Domain ip6设置的域名
     */
    Client.handleIpv6 = function (client, ipv6Domain) {
        var key = ipv6Domain.substring(0, ipv6Domain.indexOf("."));
        var domain = ipv6Domain.substring(ipv6Domain.indexOf(".") + 1);
        //获取ipv6
        var changeResult = { domain: "", change: false, before: "", after: "", rr: "" };
        this.getIpv6().then(function (res) {
            return __awaiter(this, void 0, void 0, function () {
                var ipv6, describeDomainRecordsRequest, resp, queryResult, resultObj, domanResult, updateDomainRecordRequest, updateResp, error_2, addDomainRecordRequest, addResp;
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0:
                            ipv6 = res.data;
                            if (!res.result) return [3 /*break*/, 9];
                            describeDomainRecordsRequest = new $Alidns20150109.DescribeDomainRecordsRequest({
                                domainName: domain,
                                typeKeyWord: "AAAA",
                                RRKeyWord: key,
                                recordId: "1"
                            });
                            console.log("处理ipv6----查询域名解析记录-开始:" + tea_util_1["default"].toJSONString($tea.toMap(describeDomainRecordsRequest)));
                            return [4 /*yield*/, client.describeDomainRecords(describeDomainRecordsRequest)];
                        case 1:
                            resp = _a.sent();
                            queryResult = tea_util_1["default"].toJSONString(resp.body.domainRecords);
                            resultObj = JSON.parse(queryResult);
                            domanResult = resultObj.record[0];
                            console.log("处理ipv6----查询域名解析记录-结果:" + queryResult);
                            changeResult.domain = domain;
                            changeResult.rr = key;
                            if (!domanResult) return [3 /*break*/, 6];
                            changeResult.before = domanResult.value;
                            changeResult.after = ipv6;
                            updateDomainRecordRequest = new $Alidns20150109.UpdateDomainRecordRequest({
                                TTL: 600,
                                priority: 1,
                                value: ipv6,
                                type: "AAAA",
                                RR: key,
                                recordId: domanResult.recordId
                            });
                            console.log("处理ipv6----更新域名解析记录-开始:" + tea_util_1["default"].toJSONString($tea.toMap(updateDomainRecordRequest)));
                            _a.label = 2;
                        case 2:
                            _a.trys.push([2, 4, , 5]);
                            return [4 /*yield*/, client.updateDomainRecord(updateDomainRecordRequest)];
                        case 3:
                            updateResp = _a.sent();
                            console.log("处理ipv6----更新域名解析记录-完成:" + tea_util_1["default"].toJSONString($tea.toMap(updateResp)));
                            return [3 /*break*/, 5];
                        case 4:
                            error_2 = _a.sent();
                            console.log("处理ipv6----更新域名解析记录-完成:本次ip没有改变:" + error_2);
                            return [3 /*break*/, 5];
                        case 5: return [3 /*break*/, 8];
                        case 6:
                            addDomainRecordRequest = new $Alidns20150109.AddDomainRecordRequest({
                                TTL: 600,
                                priority: 1,
                                value: ipv6,
                                type: "AAAA",
                                domainName: domain,
                                RR: key
                            });
                            console.log("处理ipv6----新增域名解析记录-开始:" + tea_util_1["default"].toJSONString($tea.toMap(addDomainRecordRequest)));
                            return [4 /*yield*/, client.addDomainRecord(addDomainRecordRequest)];
                        case 7:
                            addResp = _a.sent();
                            changeResult.before = "无";
                            changeResult.after = ipv6;
                            changeResult.change = true;
                            console.log("处理ipv6----新增域名解析记录-完成:" + tea_util_1["default"].toJSONString($tea.toMap(addResp)));
                            Client.pushNotice(null, changeResult);
                            _a.label = 8;
                        case 8: return [3 /*break*/, 10];
                        case 9:
                            console.error("处理ipv6----ipv6获取异常,跳过处理ipv4!");
                            _a.label = 10;
                        case 10: return [2 /*return*/];
                    }
                });
            });
        });
    };
    /**
     *
     * @returns 主方法
     */
    Client.main = function () {
        return __awaiter(this, void 0, void 0, function () {
            var DDNS_ALI_AK, DDNS_ALI_SK, client, ipv6Domain, ipv4Domain;
            return __generator(this, function (_a) {
                console.log("----------------开始同步域名解析记录-----------------");
                DDNS_ALI_AK = process.env.DDNS_ALI_AK;
                DDNS_ALI_SK = process.env.DDNS_ALI_SK;
                if (!DDNS_ALI_AK || DDNS_ALI_AK == "") {
                    console.log("请在环境变量里填写阿里云accessKey:DDNS_ALI_AK=");
                    return [2 /*return*/];
                }
                if (!DDNS_ALI_SK || DDNS_ALI_AK == "") {
                    console.log("请在环境变量里填写阿里云secretKey:DDNS_ALI_SK=");
                    return [2 /*return*/];
                }
                client = Client.createClient(DDNS_ALI_AK, DDNS_ALI_SK);
                ipv6Domain = process.env.DDNS_IP6_DOMAIN ? process.env.DDNS_IP6_DOMAIN : "";
                if (ipv6Domain != "") {
                    this.handleIpv6(client, ipv6Domain);
                }
                ipv4Domain = process.env.DDNS_IP4_DOMAIN ? process.env.DDNS_IP4_DOMAIN : "";
                if (ipv4Domain != "") {
                    this.handleIpv4(client, ipv4Domain);
                }
                return [2 /*return*/];
            });
        });
    };
    Client.pushNotice = function (changeIp4Result, changeIp6Result) {
        var plshType = process.env.DDNS_PUSH_TYPE;
        if (plshType) {
            var content_1 = PushUtil.html_template;
            if (changeIp4Result != null && changeIp4Result.change) {
                console.log("您的域名解析发生变更--ipv4变更:" + tea_util_1["default"].toJSONString($tea.toMap(changeIp4Result)));
                var ip4Html = PushUtil.ip4_template.replace("IP4_KEY", changeIp4Result.rr).
                    replace("IP4_CHANGE_BEFORE", changeIp4Result.before).
                    replace("IP4_CHANGE_AFTER", changeIp4Result.after);
                content_1 = content_1.replace("IP4_LINE", ip4Html);
                content_1 = content_1.replace("IP6_LINE", "").replace("IP4_LINE", "");
                var title_1 = "您的域名[" + changeIp4Result.domain + "]解析发生变更!";
                PushUtil.pushConfigs.forEach(function (obj, index) {
                    if (plshType == obj.type()) {
                        obj.push(title_1, content_1);
                    }
                });
            }
            if (changeIp6Result != null && changeIp6Result.change) {
                console.log("您的域名解析发生变更--ipv6变更:" + tea_util_1["default"].toJSONString($tea.toMap(changeIp6Result)));
                var ip6Html = PushUtil.ip6_template.replace("IP6_KEY", changeIp6Result.rr).
                    replace("IP6_CHANGE_BEFORE", changeIp6Result.before).
                    replace("IP6_CHANGE_AFTER", changeIp6Result.after);
                content_1 = content_1.replace("IP6_LINE", ip6Html);
                content_1 = content_1.replace("IP6_LINE", "").replace("IP4_LINE", "");
                var title_2 = "您的域名[" + changeIp6Result.domain + "]解析发生变更!";
                PushUtil.pushConfigs.forEach(function (obj, index) {
                    if (plshType == obj.type()) {
                        obj.push(title_2, content_1);
                    }
                });
            }
        }
    };
    return Client;
}());
exports["default"] = Client;
//Client.getIpv4()
//Client.getIpv6()
//console.log(process.env.DDNS_IP4_DOMAIN)
Client.main();
